{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Example CV3 - Function fitting with a quantum neural network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this example we show how a variational circuit can be used to learn a fit for a one-dimensional function when being trained with noisy samples from that function. \n",
    "\n",
    "The variational circuit we use is the continuous-variable quantum neural network model described in [Killoran et al. (2018)](https://arxiv.org/abs/1806.06871). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Imports"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We import PennyLane, the wrapped version of NumPy provided by PennyLane, and an optimizer. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pennylane as qml\n",
    "from pennylane import numpy as np\n",
    "from pennylane.optimize import AdamOptimizer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The device we use is the Strawberry Fields simulator, this time with only one quantum mode (or `wire`). You will need to have the Strawberry Fields plugin for PennyLane installed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    dev = qml.device('strawberryfields.fock', wires=1, cutoff_dim=10)    \n",
    "except:\n",
    "    print(\"To run this example you need to install the strawberryfields plugin...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Quantum node\n",
    "\n",
    "For a single quantum mode, each layer of the variational circuit is defined as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def layer(v):\n",
    "\n",
    "    # Matrix multiplication of input layer\n",
    "    qml.Rotation(v[0], wires=0)\n",
    "    qml.Squeezing(v[1], 0., wires=0)\n",
    "    qml.Rotation(v[2], wires=0)\n",
    "\n",
    "    # Bias\n",
    "    qml.Displacement(v[3], 0., wires=0)\n",
    "\n",
    "    # Element-wise nonlinear transformation\n",
    "    qml.Kerr(v[4], wires=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The variational circuit in the quantum node first encodes the input into the displacement of the mode, and then executes the layers. The output is the expectation of the x-quadrature."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "@qml.qnode(dev)\n",
    "def quantum_neural_net(var, x=None):\n",
    "    \n",
    "    # Encode input x into quantum state\n",
    "    qml.Displacement(x, 0., wires=0)\n",
    "\n",
    "    # \"layer\" subcircuits\n",
    "    for v in var:\n",
    "        layer(v)\n",
    "\n",
    "    return qml.expval.X(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Objective"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As an objective we take the square loss between target labels and model predictions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def square_loss(labels, predictions):\n",
    "\n",
    "    loss = 0\n",
    "    for l, p in zip(labels, predictions):\n",
    "        loss = loss + (l - p) ** 2\n",
    "    loss = loss / len(labels)\n",
    "\n",
    "    return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the cost function, we compute the outputs from the variational circuit. Function fitting is a regression problem, and we interpret the expectations from the quantum node as predictions (i.e., without applying postprocessing such as thresholding)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cost(var, features, labels):\n",
    "\n",
    "    preds = [quantum_neural_net(var, x=x) for x in features]\n",
    "\n",
    "    return square_loss(labels, preds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Optimization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We load noisy data samples of a sine function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.loadtxt(\"data/sine.txt\")\n",
    "X = data[:, 0]\n",
    "Y = data[:, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before training a model, let's examine the data.\n",
    "\n",
    "*Note: For the next cell to work you need the matplotlib library.* "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline  \n",
    "\n",
    "plt.figure()\n",
    "plt.scatter(X, Y)\n",
    "plt.xlabel('x', fontsize=18)\n",
    "plt.ylabel('f(x)', fontsize=18)\n",
    "plt.tick_params(axis='both', which='major', labelsize=16)\n",
    "plt.tick_params(axis='both', which='minor', labelsize=16)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The network's weights (called `var` here) are initialized with values sampled from a normal distribution. We use 4 layers; performance has been found to plateau at around 6 layers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.08820262,  0.02000786,  0.0489369 ,  0.11204466,  0.0933779 ],\n",
       "       [-0.04886389,  0.04750442, -0.00756786, -0.00516094,  0.02052993],\n",
       "       [ 0.00720218,  0.07271368,  0.03805189,  0.00608375,  0.02219316],\n",
       "       [ 0.01668372,  0.07470395, -0.01025791,  0.01565339, -0.04270479]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.seed(0)\n",
    "num_layers = 4\n",
    "var_init = 0.05 * np.random.randn(num_layers, 5)\n",
    "\n",
    "var_init"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the Adam optimizer, we update the weights for 500 steps (this takes some time). More steps will lead to a better fit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iter:     1 | Cost: 0.2689702 \n",
      "Iter:     2 | Cost: 0.2472125 \n",
      "Iter:     3 | Cost: 0.2300139 \n",
      "Iter:     4 | Cost: 0.2157100 \n",
      "Iter:     5 | Cost: 0.2035455 \n",
      "Iter:     6 | Cost: 0.1931103 \n",
      "Iter:     7 | Cost: 0.1841536 \n",
      "Iter:     8 | Cost: 0.1765061 \n",
      "Iter:     9 | Cost: 0.1700410 \n",
      "Iter:    10 | Cost: 0.1646527 \n",
      "Iter:    11 | Cost: 0.1602444 \n",
      "Iter:    12 | Cost: 0.1567201 \n",
      "Iter:    13 | Cost: 0.1539806 \n",
      "Iter:    14 | Cost: 0.1519220 \n",
      "Iter:    15 | Cost: 0.1504356 \n",
      "Iter:    16 | Cost: 0.1494099 \n",
      "Iter:    17 | Cost: 0.1487330 \n",
      "Iter:    18 | Cost: 0.1482962 \n",
      "Iter:    19 | Cost: 0.1479980 \n",
      "Iter:    20 | Cost: 0.1477470 \n",
      "Iter:    21 | Cost: 0.1474655 \n",
      "Iter:    22 | Cost: 0.1470914 \n",
      "Iter:    23 | Cost: 0.1465799 \n",
      "Iter:    24 | Cost: 0.1459034 \n",
      "Iter:    25 | Cost: 0.1450506 \n",
      "Iter:    26 | Cost: 0.1440251 \n",
      "Iter:    27 | Cost: 0.1428427 \n",
      "Iter:    28 | Cost: 0.1415282 \n",
      "Iter:    29 | Cost: 0.1401125 \n",
      "Iter:    30 | Cost: 0.1386296 \n",
      "Iter:    31 | Cost: 0.1371132 \n",
      "Iter:    32 | Cost: 0.1355946 \n",
      "Iter:    33 | Cost: 0.1341006 \n",
      "Iter:    34 | Cost: 0.1326526 \n",
      "Iter:    35 | Cost: 0.1312654 \n",
      "Iter:    36 | Cost: 0.1299478 \n",
      "Iter:    37 | Cost: 0.1287022 \n",
      "Iter:    38 | Cost: 0.1275259 \n",
      "Iter:    39 | Cost: 0.1264120 \n",
      "Iter:    40 | Cost: 0.1253502 \n",
      "Iter:    41 | Cost: 0.1243284 \n",
      "Iter:    42 | Cost: 0.1233333 \n",
      "Iter:    43 | Cost: 0.1223521 \n",
      "Iter:    44 | Cost: 0.1213726 \n",
      "Iter:    45 | Cost: 0.1203843 \n",
      "Iter:    46 | Cost: 0.1193790 \n",
      "Iter:    47 | Cost: 0.1183506 \n",
      "Iter:    48 | Cost: 0.1172959 \n",
      "Iter:    49 | Cost: 0.1162138 \n",
      "Iter:    50 | Cost: 0.1151057 \n",
      "Iter:    51 | Cost: 0.1139748 \n",
      "Iter:    52 | Cost: 0.1128259 \n",
      "Iter:    53 | Cost: 0.1116647 \n",
      "Iter:    54 | Cost: 0.1104972 \n",
      "Iter:    55 | Cost: 0.1093295 \n",
      "Iter:    56 | Cost: 0.1081673 \n",
      "Iter:    57 | Cost: 0.1070151 \n",
      "Iter:    58 | Cost: 0.1058764 \n",
      "Iter:    59 | Cost: 0.1047533 \n",
      "Iter:    60 | Cost: 0.1036464 \n",
      "Iter:    61 | Cost: 0.1025554 \n",
      "Iter:    62 | Cost: 0.1014787 \n",
      "Iter:    63 | Cost: 0.1004141 \n",
      "Iter:    64 | Cost: 0.0993591 \n",
      "Iter:    65 | Cost: 0.0983111 \n",
      "Iter:    66 | Cost: 0.0972679 \n",
      "Iter:    67 | Cost: 0.0962278 \n",
      "Iter:    68 | Cost: 0.0951897 \n",
      "Iter:    69 | Cost: 0.0941534 \n",
      "Iter:    70 | Cost: 0.0931195 \n",
      "Iter:    71 | Cost: 0.0920891 \n",
      "Iter:    72 | Cost: 0.0910638 \n",
      "Iter:    73 | Cost: 0.0900453 \n",
      "Iter:    74 | Cost: 0.0890357 \n",
      "Iter:    75 | Cost: 0.0880366 \n",
      "Iter:    76 | Cost: 0.0870493 \n",
      "Iter:    77 | Cost: 0.0860751 \n",
      "Iter:    78 | Cost: 0.0851144 \n",
      "Iter:    79 | Cost: 0.0841675 \n",
      "Iter:    80 | Cost: 0.0832342 \n",
      "Iter:    81 | Cost: 0.0823143 \n",
      "Iter:    82 | Cost: 0.0814072 \n",
      "Iter:    83 | Cost: 0.0805125 \n",
      "Iter:    84 | Cost: 0.0796296 \n",
      "Iter:    85 | Cost: 0.0787583 \n",
      "Iter:    86 | Cost: 0.0778983 \n",
      "Iter:    87 | Cost: 0.0770497 \n",
      "Iter:    88 | Cost: 0.0762127 \n",
      "Iter:    89 | Cost: 0.0753874 \n",
      "Iter:    90 | Cost: 0.0745742 \n",
      "Iter:    91 | Cost: 0.0737733 \n",
      "Iter:    92 | Cost: 0.0729849 \n",
      "Iter:    93 | Cost: 0.0722092 \n",
      "Iter:    94 | Cost: 0.0714462 \n",
      "Iter:    95 | Cost: 0.0706958 \n",
      "Iter:    96 | Cost: 0.0699578 \n",
      "Iter:    97 | Cost: 0.0692319 \n",
      "Iter:    98 | Cost: 0.0685177 \n",
      "Iter:    99 | Cost: 0.0678151 \n",
      "Iter:   100 | Cost: 0.0671236 \n",
      "Iter:   101 | Cost: 0.0664430 \n",
      "Iter:   102 | Cost: 0.0657732 \n",
      "Iter:   103 | Cost: 0.0651139 \n",
      "Iter:   104 | Cost: 0.0644650 \n",
      "Iter:   105 | Cost: 0.0638264 \n",
      "Iter:   106 | Cost: 0.0631981 \n",
      "Iter:   107 | Cost: 0.0625800 \n",
      "Iter:   108 | Cost: 0.0619719 \n",
      "Iter:   109 | Cost: 0.0613737 \n",
      "Iter:   110 | Cost: 0.0607853 \n",
      "Iter:   111 | Cost: 0.0602064 \n",
      "Iter:   112 | Cost: 0.0596368 \n",
      "Iter:   113 | Cost: 0.0590764 \n",
      "Iter:   114 | Cost: 0.0585249 \n",
      "Iter:   115 | Cost: 0.0579820 \n",
      "Iter:   116 | Cost: 0.0574476 \n",
      "Iter:   117 | Cost: 0.0569214 \n",
      "Iter:   118 | Cost: 0.0564033 \n",
      "Iter:   119 | Cost: 0.0558932 \n",
      "Iter:   120 | Cost: 0.0553908 \n",
      "Iter:   121 | Cost: 0.0548960 \n",
      "Iter:   122 | Cost: 0.0544086 \n",
      "Iter:   123 | Cost: 0.0539286 \n",
      "Iter:   124 | Cost: 0.0534557 \n",
      "Iter:   125 | Cost: 0.0529897 \n",
      "Iter:   126 | Cost: 0.0525306 \n",
      "Iter:   127 | Cost: 0.0520781 \n",
      "Iter:   128 | Cost: 0.0516320 \n",
      "Iter:   129 | Cost: 0.0511923 \n",
      "Iter:   130 | Cost: 0.0507587 \n",
      "Iter:   131 | Cost: 0.0503311 \n",
      "Iter:   132 | Cost: 0.0499094 \n",
      "Iter:   133 | Cost: 0.0494934 \n",
      "Iter:   134 | Cost: 0.0490830 \n",
      "Iter:   135 | Cost: 0.0486781 \n",
      "Iter:   136 | Cost: 0.0482785 \n",
      "Iter:   137 | Cost: 0.0478842 \n",
      "Iter:   138 | Cost: 0.0474949 \n",
      "Iter:   139 | Cost: 0.0471107 \n",
      "Iter:   140 | Cost: 0.0467313 \n",
      "Iter:   141 | Cost: 0.0463567 \n",
      "Iter:   142 | Cost: 0.0459868 \n",
      "Iter:   143 | Cost: 0.0456214 \n",
      "Iter:   144 | Cost: 0.0452604 \n",
      "Iter:   145 | Cost: 0.0449038 \n",
      "Iter:   146 | Cost: 0.0445514 \n",
      "Iter:   147 | Cost: 0.0442032 \n",
      "Iter:   148 | Cost: 0.0438590 \n",
      "Iter:   149 | Cost: 0.0435188 \n",
      "Iter:   150 | Cost: 0.0431825 \n",
      "Iter:   151 | Cost: 0.0428499 \n",
      "Iter:   152 | Cost: 0.0425211 \n",
      "Iter:   153 | Cost: 0.0421960 \n",
      "Iter:   154 | Cost: 0.0418744 \n",
      "Iter:   155 | Cost: 0.0415563 \n",
      "Iter:   156 | Cost: 0.0412416 \n",
      "Iter:   157 | Cost: 0.0409302 \n",
      "Iter:   158 | Cost: 0.0406222 \n",
      "Iter:   159 | Cost: 0.0403173 \n",
      "Iter:   160 | Cost: 0.0400156 \n",
      "Iter:   161 | Cost: 0.0397169 \n",
      "Iter:   162 | Cost: 0.0394213 \n",
      "Iter:   163 | Cost: 0.0391286 \n",
      "Iter:   164 | Cost: 0.0388389 \n",
      "Iter:   165 | Cost: 0.0385520 \n",
      "Iter:   166 | Cost: 0.0382679 \n",
      "Iter:   167 | Cost: 0.0379866 \n",
      "Iter:   168 | Cost: 0.0377079 \n",
      "Iter:   169 | Cost: 0.0374319 \n",
      "Iter:   170 | Cost: 0.0371585 \n",
      "Iter:   171 | Cost: 0.0368877 \n",
      "Iter:   172 | Cost: 0.0366194 \n",
      "Iter:   173 | Cost: 0.0363535 \n",
      "Iter:   174 | Cost: 0.0360901 \n",
      "Iter:   175 | Cost: 0.0358291 \n",
      "Iter:   176 | Cost: 0.0355704 \n",
      "Iter:   177 | Cost: 0.0353140 \n",
      "Iter:   178 | Cost: 0.0350599 \n",
      "Iter:   179 | Cost: 0.0348081 \n",
      "Iter:   180 | Cost: 0.0345585 \n",
      "Iter:   181 | Cost: 0.0343110 \n",
      "Iter:   182 | Cost: 0.0340658 \n",
      "Iter:   183 | Cost: 0.0338226 \n",
      "Iter:   184 | Cost: 0.0335815 \n",
      "Iter:   185 | Cost: 0.0333425 \n",
      "Iter:   186 | Cost: 0.0331056 \n",
      "Iter:   187 | Cost: 0.0328706 \n",
      "Iter:   188 | Cost: 0.0326377 \n",
      "Iter:   189 | Cost: 0.0324067 \n",
      "Iter:   190 | Cost: 0.0321777 \n",
      "Iter:   191 | Cost: 0.0319506 \n",
      "Iter:   192 | Cost: 0.0317255 \n",
      "Iter:   193 | Cost: 0.0315022 \n",
      "Iter:   194 | Cost: 0.0312808 \n",
      "Iter:   195 | Cost: 0.0310613 \n",
      "Iter:   196 | Cost: 0.0308436 \n",
      "Iter:   197 | Cost: 0.0306278 \n",
      "Iter:   198 | Cost: 0.0304138 \n",
      "Iter:   199 | Cost: 0.0302016 \n",
      "Iter:   200 | Cost: 0.0299912 \n",
      "Iter:   201 | Cost: 0.0297826 \n",
      "Iter:   202 | Cost: 0.0295757 \n",
      "Iter:   203 | Cost: 0.0293707 \n",
      "Iter:   204 | Cost: 0.0291674 \n",
      "Iter:   205 | Cost: 0.0289659 \n",
      "Iter:   206 | Cost: 0.0287661 \n",
      "Iter:   207 | Cost: 0.0285681 \n",
      "Iter:   208 | Cost: 0.0283718 \n",
      "Iter:   209 | Cost: 0.0281772 \n",
      "Iter:   210 | Cost: 0.0279844 \n",
      "Iter:   211 | Cost: 0.0277933 \n",
      "Iter:   212 | Cost: 0.0276039 \n",
      "Iter:   213 | Cost: 0.0274163 \n",
      "Iter:   214 | Cost: 0.0272304 \n",
      "Iter:   215 | Cost: 0.0270461 \n",
      "Iter:   216 | Cost: 0.0268636 \n",
      "Iter:   217 | Cost: 0.0266829 \n",
      "Iter:   218 | Cost: 0.0265038 \n",
      "Iter:   219 | Cost: 0.0263264 \n",
      "Iter:   220 | Cost: 0.0261508 \n",
      "Iter:   221 | Cost: 0.0259768 \n",
      "Iter:   222 | Cost: 0.0258046 \n",
      "Iter:   223 | Cost: 0.0256341 \n",
      "Iter:   224 | Cost: 0.0254652 \n",
      "Iter:   225 | Cost: 0.0252981 \n",
      "Iter:   226 | Cost: 0.0251327 \n",
      "Iter:   227 | Cost: 0.0249690 \n",
      "Iter:   228 | Cost: 0.0248070 \n",
      "Iter:   229 | Cost: 0.0246467 \n",
      "Iter:   230 | Cost: 0.0244881 \n",
      "Iter:   231 | Cost: 0.0243312 \n",
      "Iter:   232 | Cost: 0.0241760 \n",
      "Iter:   233 | Cost: 0.0240225 \n",
      "Iter:   234 | Cost: 0.0238707 \n",
      "Iter:   235 | Cost: 0.0237206 \n",
      "Iter:   236 | Cost: 0.0235721 \n",
      "Iter:   237 | Cost: 0.0234254 \n",
      "Iter:   238 | Cost: 0.0232803 \n",
      "Iter:   239 | Cost: 0.0231369 \n",
      "Iter:   240 | Cost: 0.0229952 \n",
      "Iter:   241 | Cost: 0.0228552 \n",
      "Iter:   242 | Cost: 0.0227168 \n",
      "Iter:   243 | Cost: 0.0225801 \n",
      "Iter:   244 | Cost: 0.0224450 \n",
      "Iter:   245 | Cost: 0.0223116 \n",
      "Iter:   246 | Cost: 0.0221798 \n",
      "Iter:   247 | Cost: 0.0220496 \n",
      "Iter:   248 | Cost: 0.0219211 \n",
      "Iter:   249 | Cost: 0.0217942 \n",
      "Iter:   250 | Cost: 0.0216688 \n",
      "Iter:   251 | Cost: 0.0215451 \n",
      "Iter:   252 | Cost: 0.0214230 \n",
      "Iter:   253 | Cost: 0.0213024 \n",
      "Iter:   254 | Cost: 0.0211835 \n",
      "Iter:   255 | Cost: 0.0210660 \n",
      "Iter:   256 | Cost: 0.0209502 \n",
      "Iter:   257 | Cost: 0.0208358 \n",
      "Iter:   258 | Cost: 0.0207230 \n",
      "Iter:   259 | Cost: 0.0206117 \n",
      "Iter:   260 | Cost: 0.0205019 \n",
      "Iter:   261 | Cost: 0.0203936 \n",
      "Iter:   262 | Cost: 0.0202867 \n",
      "Iter:   263 | Cost: 0.0201813 \n",
      "Iter:   264 | Cost: 0.0200773 \n",
      "Iter:   265 | Cost: 0.0199748 \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iter:   266 | Cost: 0.0198737 \n",
      "Iter:   267 | Cost: 0.0197740 \n",
      "Iter:   268 | Cost: 0.0196757 \n",
      "Iter:   269 | Cost: 0.0195787 \n",
      "Iter:   270 | Cost: 0.0194831 \n",
      "Iter:   271 | Cost: 0.0193889 \n",
      "Iter:   272 | Cost: 0.0192959 \n",
      "Iter:   273 | Cost: 0.0192043 \n",
      "Iter:   274 | Cost: 0.0191140 \n",
      "Iter:   275 | Cost: 0.0190249 \n",
      "Iter:   276 | Cost: 0.0189371 \n",
      "Iter:   277 | Cost: 0.0188505 \n",
      "Iter:   278 | Cost: 0.0187651 \n",
      "Iter:   279 | Cost: 0.0186810 \n",
      "Iter:   280 | Cost: 0.0185980 \n",
      "Iter:   281 | Cost: 0.0185163 \n",
      "Iter:   282 | Cost: 0.0184356 \n",
      "Iter:   283 | Cost: 0.0183561 \n",
      "Iter:   284 | Cost: 0.0182777 \n",
      "Iter:   285 | Cost: 0.0182004 \n",
      "Iter:   286 | Cost: 0.0181242 \n",
      "Iter:   287 | Cost: 0.0180491 \n",
      "Iter:   288 | Cost: 0.0179750 \n",
      "Iter:   289 | Cost: 0.0179020 \n",
      "Iter:   290 | Cost: 0.0178299 \n",
      "Iter:   291 | Cost: 0.0177589 \n",
      "Iter:   292 | Cost: 0.0176888 \n",
      "Iter:   293 | Cost: 0.0176197 \n",
      "Iter:   294 | Cost: 0.0175515 \n",
      "Iter:   295 | Cost: 0.0174843 \n",
      "Iter:   296 | Cost: 0.0174180 \n",
      "Iter:   297 | Cost: 0.0173525 \n",
      "Iter:   298 | Cost: 0.0172880 \n",
      "Iter:   299 | Cost: 0.0172243 \n",
      "Iter:   300 | Cost: 0.0171614 \n",
      "Iter:   301 | Cost: 0.0170994 \n",
      "Iter:   302 | Cost: 0.0170382 \n",
      "Iter:   303 | Cost: 0.0169777 \n",
      "Iter:   304 | Cost: 0.0169181 \n",
      "Iter:   305 | Cost: 0.0168592 \n",
      "Iter:   306 | Cost: 0.0168010 \n",
      "Iter:   307 | Cost: 0.0167436 \n",
      "Iter:   308 | Cost: 0.0166869 \n",
      "Iter:   309 | Cost: 0.0166309 \n",
      "Iter:   310 | Cost: 0.0165756 \n",
      "Iter:   311 | Cost: 0.0165209 \n",
      "Iter:   312 | Cost: 0.0164669 \n",
      "Iter:   313 | Cost: 0.0164136 \n",
      "Iter:   314 | Cost: 0.0163608 \n",
      "Iter:   315 | Cost: 0.0163087 \n",
      "Iter:   316 | Cost: 0.0162572 \n",
      "Iter:   317 | Cost: 0.0162063 \n",
      "Iter:   318 | Cost: 0.0161559 \n",
      "Iter:   319 | Cost: 0.0161061 \n",
      "Iter:   320 | Cost: 0.0160568 \n",
      "Iter:   321 | Cost: 0.0160080 \n",
      "Iter:   322 | Cost: 0.0159598 \n",
      "Iter:   323 | Cost: 0.0159121 \n",
      "Iter:   324 | Cost: 0.0158649 \n",
      "Iter:   325 | Cost: 0.0158181 \n",
      "Iter:   326 | Cost: 0.0157719 \n",
      "Iter:   327 | Cost: 0.0157260 \n",
      "Iter:   328 | Cost: 0.0156807 \n",
      "Iter:   329 | Cost: 0.0156357 \n",
      "Iter:   330 | Cost: 0.0155912 \n",
      "Iter:   331 | Cost: 0.0155471 \n",
      "Iter:   332 | Cost: 0.0155034 \n",
      "Iter:   333 | Cost: 0.0154601 \n",
      "Iter:   334 | Cost: 0.0154172 \n",
      "Iter:   335 | Cost: 0.0153747 \n",
      "Iter:   336 | Cost: 0.0153325 \n",
      "Iter:   337 | Cost: 0.0152907 \n",
      "Iter:   338 | Cost: 0.0152492 \n",
      "Iter:   339 | Cost: 0.0152081 \n",
      "Iter:   340 | Cost: 0.0151673 \n",
      "Iter:   341 | Cost: 0.0151269 \n",
      "Iter:   342 | Cost: 0.0150867 \n",
      "Iter:   343 | Cost: 0.0150469 \n",
      "Iter:   344 | Cost: 0.0150073 \n",
      "Iter:   345 | Cost: 0.0149681 \n",
      "Iter:   346 | Cost: 0.0149291 \n",
      "Iter:   347 | Cost: 0.0148905 \n",
      "Iter:   348 | Cost: 0.0148521 \n",
      "Iter:   349 | Cost: 0.0148140 \n",
      "Iter:   350 | Cost: 0.0147761 \n",
      "Iter:   351 | Cost: 0.0147385 \n",
      "Iter:   352 | Cost: 0.0147012 \n",
      "Iter:   353 | Cost: 0.0146641 \n",
      "Iter:   354 | Cost: 0.0146273 \n",
      "Iter:   355 | Cost: 0.0145907 \n",
      "Iter:   356 | Cost: 0.0145543 \n",
      "Iter:   357 | Cost: 0.0145182 \n",
      "Iter:   358 | Cost: 0.0144824 \n",
      "Iter:   359 | Cost: 0.0144467 \n",
      "Iter:   360 | Cost: 0.0144113 \n",
      "Iter:   361 | Cost: 0.0143762 \n",
      "Iter:   362 | Cost: 0.0143412 \n",
      "Iter:   363 | Cost: 0.0143065 \n",
      "Iter:   364 | Cost: 0.0142720 \n",
      "Iter:   365 | Cost: 0.0142378 \n",
      "Iter:   366 | Cost: 0.0142037 \n",
      "Iter:   367 | Cost: 0.0141699 \n",
      "Iter:   368 | Cost: 0.0141363 \n",
      "Iter:   369 | Cost: 0.0141030 \n",
      "Iter:   370 | Cost: 0.0140699 \n",
      "Iter:   371 | Cost: 0.0140370 \n",
      "Iter:   372 | Cost: 0.0140043 \n",
      "Iter:   373 | Cost: 0.0139719 \n",
      "Iter:   374 | Cost: 0.0139397 \n",
      "Iter:   375 | Cost: 0.0139077 \n",
      "Iter:   376 | Cost: 0.0138760 \n",
      "Iter:   377 | Cost: 0.0138445 \n",
      "Iter:   378 | Cost: 0.0138132 \n",
      "Iter:   379 | Cost: 0.0137822 \n",
      "Iter:   380 | Cost: 0.0137515 \n",
      "Iter:   381 | Cost: 0.0137210 \n",
      "Iter:   382 | Cost: 0.0136907 \n",
      "Iter:   383 | Cost: 0.0136607 \n",
      "Iter:   384 | Cost: 0.0136310 \n",
      "Iter:   385 | Cost: 0.0136015 \n",
      "Iter:   386 | Cost: 0.0135723 \n",
      "Iter:   387 | Cost: 0.0135433 \n",
      "Iter:   388 | Cost: 0.0135146 \n",
      "Iter:   389 | Cost: 0.0134863 \n",
      "Iter:   390 | Cost: 0.0134581 \n",
      "Iter:   391 | Cost: 0.0134303 \n",
      "Iter:   392 | Cost: 0.0134027 \n",
      "Iter:   393 | Cost: 0.0133755 \n",
      "Iter:   394 | Cost: 0.0133485 \n",
      "Iter:   395 | Cost: 0.0133218 \n",
      "Iter:   396 | Cost: 0.0132954 \n",
      "Iter:   397 | Cost: 0.0132694 \n",
      "Iter:   398 | Cost: 0.0132436 \n",
      "Iter:   399 | Cost: 0.0132181 \n",
      "Iter:   400 | Cost: 0.0131929 \n",
      "Iter:   401 | Cost: 0.0131681 \n",
      "Iter:   402 | Cost: 0.0131435 \n",
      "Iter:   403 | Cost: 0.0131193 \n",
      "Iter:   404 | Cost: 0.0130953 \n",
      "Iter:   405 | Cost: 0.0130717 \n",
      "Iter:   406 | Cost: 0.0130484 \n",
      "Iter:   407 | Cost: 0.0130254 \n",
      "Iter:   408 | Cost: 0.0130028 \n",
      "Iter:   409 | Cost: 0.0129804 \n",
      "Iter:   410 | Cost: 0.0129584 \n",
      "Iter:   411 | Cost: 0.0129367 \n",
      "Iter:   412 | Cost: 0.0129153 \n",
      "Iter:   413 | Cost: 0.0128942 \n",
      "Iter:   414 | Cost: 0.0128735 \n",
      "Iter:   415 | Cost: 0.0128530 \n",
      "Iter:   416 | Cost: 0.0128329 \n",
      "Iter:   417 | Cost: 0.0128131 \n",
      "Iter:   418 | Cost: 0.0127935 \n",
      "Iter:   419 | Cost: 0.0127743 \n",
      "Iter:   420 | Cost: 0.0127554 \n",
      "Iter:   421 | Cost: 0.0127368 \n",
      "Iter:   422 | Cost: 0.0127185 \n",
      "Iter:   423 | Cost: 0.0127006 \n",
      "Iter:   424 | Cost: 0.0126829 \n",
      "Iter:   425 | Cost: 0.0126655 \n",
      "Iter:   426 | Cost: 0.0126483 \n",
      "Iter:   427 | Cost: 0.0126315 \n",
      "Iter:   428 | Cost: 0.0126150 \n",
      "Iter:   429 | Cost: 0.0125987 \n",
      "Iter:   430 | Cost: 0.0125827 \n",
      "Iter:   431 | Cost: 0.0125670 \n",
      "Iter:   432 | Cost: 0.0125516 \n",
      "Iter:   433 | Cost: 0.0125364 \n",
      "Iter:   434 | Cost: 0.0125215 \n",
      "Iter:   435 | Cost: 0.0125068 \n",
      "Iter:   436 | Cost: 0.0124924 \n",
      "Iter:   437 | Cost: 0.0124782 \n",
      "Iter:   438 | Cost: 0.0124643 \n",
      "Iter:   439 | Cost: 0.0124507 \n",
      "Iter:   440 | Cost: 0.0124372 \n",
      "Iter:   441 | Cost: 0.0124240 \n",
      "Iter:   442 | Cost: 0.0124110 \n",
      "Iter:   443 | Cost: 0.0123983 \n",
      "Iter:   444 | Cost: 0.0123857 \n",
      "Iter:   445 | Cost: 0.0123734 \n",
      "Iter:   446 | Cost: 0.0123613 \n",
      "Iter:   447 | Cost: 0.0123494 \n",
      "Iter:   448 | Cost: 0.0123377 \n",
      "Iter:   449 | Cost: 0.0123262 \n",
      "Iter:   450 | Cost: 0.0123149 \n",
      "Iter:   451 | Cost: 0.0123038 \n",
      "Iter:   452 | Cost: 0.0122929 \n",
      "Iter:   453 | Cost: 0.0122821 \n",
      "Iter:   454 | Cost: 0.0122715 \n",
      "Iter:   455 | Cost: 0.0122611 \n",
      "Iter:   456 | Cost: 0.0122509 \n",
      "Iter:   457 | Cost: 0.0122409 \n",
      "Iter:   458 | Cost: 0.0122310 \n",
      "Iter:   459 | Cost: 0.0122212 \n",
      "Iter:   460 | Cost: 0.0122116 \n",
      "Iter:   461 | Cost: 0.0122022 \n",
      "Iter:   462 | Cost: 0.0121929 \n",
      "Iter:   463 | Cost: 0.0121838 \n",
      "Iter:   464 | Cost: 0.0121748 \n",
      "Iter:   465 | Cost: 0.0121660 \n",
      "Iter:   466 | Cost: 0.0121572 \n",
      "Iter:   467 | Cost: 0.0121487 \n",
      "Iter:   468 | Cost: 0.0121402 \n",
      "Iter:   469 | Cost: 0.0121319 \n",
      "Iter:   470 | Cost: 0.0121237 \n",
      "Iter:   471 | Cost: 0.0121156 \n",
      "Iter:   472 | Cost: 0.0121076 \n",
      "Iter:   473 | Cost: 0.0120998 \n",
      "Iter:   474 | Cost: 0.0120921 \n",
      "Iter:   475 | Cost: 0.0120844 \n",
      "Iter:   476 | Cost: 0.0120769 \n",
      "Iter:   477 | Cost: 0.0120695 \n",
      "Iter:   478 | Cost: 0.0120622 \n",
      "Iter:   479 | Cost: 0.0120550 \n",
      "Iter:   480 | Cost: 0.0120479 \n",
      "Iter:   481 | Cost: 0.0120409 \n",
      "Iter:   482 | Cost: 0.0120340 \n",
      "Iter:   483 | Cost: 0.0120272 \n",
      "Iter:   484 | Cost: 0.0120205 \n",
      "Iter:   485 | Cost: 0.0120138 \n",
      "Iter:   486 | Cost: 0.0120073 \n",
      "Iter:   487 | Cost: 0.0120008 \n",
      "Iter:   488 | Cost: 0.0119944 \n",
      "Iter:   489 | Cost: 0.0119881 \n",
      "Iter:   490 | Cost: 0.0119819 \n",
      "Iter:   491 | Cost: 0.0119758 \n",
      "Iter:   492 | Cost: 0.0119697 \n",
      "Iter:   493 | Cost: 0.0119637 \n",
      "Iter:   494 | Cost: 0.0119578 \n",
      "Iter:   495 | Cost: 0.0119520 \n",
      "Iter:   496 | Cost: 0.0119462 \n",
      "Iter:   497 | Cost: 0.0119405 \n",
      "Iter:   498 | Cost: 0.0119349 \n",
      "Iter:   499 | Cost: 0.0119293 \n",
      "Iter:   500 | Cost: 0.0119238 \n"
     ]
    }
   ],
   "source": [
    "opt = AdamOptimizer(0.01, beta1=0.9, beta2=0.999)\n",
    "\n",
    "var = var_init\n",
    "for it in range(500):\n",
    "    var = opt.step(lambda v: cost(v, X, Y), var)\n",
    "    \n",
    "    print(\"Iter: {:5d} | Cost: {:0.7f} \".format(it + 1, cost(var, X, Y)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we collect the predictions of the trained model for 50 values in the range $[-1,1]$..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_pred = np.linspace(-1, 1, 50)\n",
    "predictions = [quantum_neural_net(var, x=x_) for x_ in x_pred]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...and plot the shape of the function that the model has \"learned\" from the noisy data (green dots)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "plt.scatter(X, Y)\n",
    "plt.scatter(x_pred, predictions, color='green')\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('f(x)')\n",
    "plt.tick_params(axis='both', which='major')\n",
    "plt.tick_params(axis='both', which='minor')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The model has learned to smooth the noisy data.\n",
    "\n",
    "In fact, we can use PennyLane to look at typical functions that the model produces without being trained at all. The shape of these functions varies significantly with the variance hyperparameter for the weight initialization. \n",
    "\n",
    "Setting this hyperparameter to a small value produces almost linear functions, since all quantum gates in the variational circuit approximately perform the identity transformation in that case. Larger values produce smoothly oscillating functions with a period that depends on the number of layers used (generically, the more layers, the smaller the period)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "variance = 1.\n",
    "\n",
    "plt.figure()\n",
    "x_pred = np.linspace(-2, 2, 50)\n",
    "for i in range(7):\n",
    "    rnd_var = variance * np.random.randn(num_layers, 7)\n",
    "    predictions = [quantum_neural_net(rnd_var, x=x_) for x_ in x_pred]\n",
    "    plt.plot(x_pred, predictions, color='black')\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('f(x)')\n",
    "plt.tick_params(axis='both', which='major')\n",
    "plt.tick_params(axis='both', which='minor')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
